package com.jintian.smart.kernel.flowable.flowable.interceptor;

import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.IdentityLinkUtil;
import org.flowable.engine.interceptor.IdentityLinkInterceptor;
import org.flowable.identitylink.api.IdentityLinkType;
import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity;
import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;

public class CustomIdentityLinkInterceptor implements IdentityLinkInterceptor {
    @Override
    public void handleCompleteTask(TaskEntity task) {
        if (Authentication.getAuthenticatedUserId() != null && task.getProcessInstanceId() != null) {
            addUserIdentityLinkToTask(task, Authentication.getAuthenticatedUserId());
        }
    }

    @Override
    public void handleAddIdentityLinkToTask(TaskEntity taskEntity, IdentityLinkEntity identityLinkEntity) {
        addUserIdentityLinkToTask(taskEntity, identityLinkEntity.getUserId());
    }

    @Override
    public void handleAddAssigneeIdentityLinkToTask(TaskEntity taskEntity, String assignee) {
        addUserIdentityLinkToTask(taskEntity, assignee);
    }

    @Override
    public void handleAddOwnerIdentityLinkToTask(TaskEntity taskEntity, String owner) {
        addUserIdentityLinkToTask(taskEntity, owner);
    }

    @Override
    public void handleCreateProcessInstance(ExecutionEntity processInstanceExecution) {
        String authenticatedUserId = Authentication.getAuthenticatedUserId();
        if (authenticatedUserId != null) {
            IdentityLinkUtil.createProcessInstanceIdentityLink(processInstanceExecution, authenticatedUserId, null, IdentityLinkType.STARTER);
        }
    }

    @Override
    public void handleCreateSubProcessInstance(ExecutionEntity subProcessInstanceExecution, ExecutionEntity superExecution) {
        String authenticatedUserId = Authentication.getAuthenticatedUserId();
        if (authenticatedUserId != null) {
            IdentityLinkUtil.createProcessInstanceIdentityLink(subProcessInstanceExecution, authenticatedUserId, null, IdentityLinkType.STARTER);
        }
    }

    protected void addUserIdentityLinkToTask(Task task, String userId) {
        if (userId != null && task.getProcessInstanceId() != null) {
            for (Object obj : task.getIdentityLinks()) {
                if (obj instanceof IdentityLinkEntity) {
                    IdentityLinkEntity identityLink = (IdentityLinkEntity) obj;
                    if (identityLink.isUser() && identityLink.getUserId().equals(userId) && IdentityLinkType.PARTICIPANT.equals(identityLink.getType())) {
                        return;
                    }
                }
            }
            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
            IdentityLinkEntity identityLinkEntity = processEngineConfiguration.getIdentityLinkServiceConfiguration()
                    .getIdentityLinkService().createTaskIdentityLink(task.getId(), userId, null, IdentityLinkType.PARTICIPANT);
            identityLinkEntity.setProcessInstanceId(task.getProcessInstanceId());

            CommandContextUtil.getHistoryManager().recordIdentityLinkCreated(identityLinkEntity);
            ((TaskEntity) task).getIdentityLinks().add(identityLinkEntity);
        }
    }
}
